﻿#pragma once

#if defined(_MSC_VER)
    #define _CRT_SECURE_NO_WARNINGS
#endif

// 包含头文件
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include <assert.h>



// 结构体自引用、类型重命名
typedef struct Node
{ // 定义结构体 Node 单向链表
    float data; // 数据域， 4 字节的整数
    struct Node* next; // 指针域，指向下一个节点； 8 字节的指针
}*link; // link 同 struct Node*

// 结构体嵌套
struct score
{
    float math; // 4 字节的浮点数
    float english; // 4 字节的浮点数
    float chinese; // 4 字节的浮点数
    float physics; // 4 字节的浮点数
    float biology; // 4 字节的浮点数
};

struct student
{
    char gender[7]; // 7 字节的字符
    char name[100]; // 100 字节的字符数组
    wchar_t age; // 2 字节的整数
    struct score score; // 结构体嵌套，成员中最大对齐数为 4 字节
    double gpa[30]; // 240 字节的浮点数数组，对齐数为 8 字节
    char address[250]; // 100 字节的字符数组
    char phone[18]; // 18 字节的整数数组
};

struct Massage
{
    char gender[16]; // 16 字节的字符
    float weight; // 4 字节的浮点数
    float height; // 4 字节的浮点数
    char phone[18]; // 18 字节的整数数组
    char address[200]; // 200 字节的字符数组
};

struct Person
{
    char name[20];
    int age;
    struct Massage detail;
};

struct A // 位域测试
{
    char _a : 2;
    char _b : 7;
    char _c : 3;
    int _d : 10; // 10 位的整数，对齐数也为 4 字节
    int _e : 22; // 与 _d 共用 4 字节，占用 4 字节（因为是 int 类型）对齐到 4 字节偏移处
    char _f : 7; // 7 位的位域，占用 1 字节，对齐到 8 字节偏移处
    //char _f : 15; // 超出位宽，报错
    //位域结构体总大小为 12 字节，因为对齐数为 4 字节
};

struct B // 位域测试
{ // 定义结构体、位域 B
    char _a : 2; // 2 位的位域，占用 2 字节
    short b; // 2 字节的整数，对齐数为 2 字节，占用 2 字节
    char _c : 3; // 3 位的位域
    char _d : 1; // 1 位的位域
    char _e : 1; // 1 位的位域 _c 到 _e 总占用 1 字节
    char _f : 4; // 4 位的位域，占用 1 字节，对齐到 4 字节偏移处
    float g; // 4 字节的浮点数，对齐数为 4 字节，对齐到 8 字节偏移处
};

extern void test_struct();
extern void struct_align();
extern void struct_print(struct Person p1, const struct Person* p2);
extern void bit_field_test();



// 通讯录测试函数
extern void main_contact();



// 宏定义部分
#define print_start_line(start_str) printf("---------- %s ----------\n", start_str)
#define print_end_line(end_str) printf("---------- %s ----------\n\n\n", end_str)

